import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.image.BufferedImage;
import java.util.ArrayList;

import javax.swing.JPanel;


public class MotionPanel extends JPanel implements KeyListener {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	private static BufferedImage grid = null;
	private static int gridSize = 40;
	
	private FrameMotionInfo[] infos = null;
	private String indexName;
	private ArrayList<Integer> indices = new ArrayList<Integer>();

	private FrameMotionInfo info = null;
	
	public int counter = 0;
	
	public MotionPanel(int width, int height){
		setSize(width, height);
		setFocusable(true);
		addKeyListener(this);
	}

	public void drawMotionInfo(FrameMotionInfo f, int index){
		this.info = f;
		this.indexName = Integer.toString(index);
		repaint();
	}
	
	public void paintMotionInfo(Graphics g){
		Graphics2D g2 = (Graphics2D)g; // we need a Graphics2D context
        if(info == null)return;
        
        int w = this.getWidth();
        int h = this.getHeight();
        if (grid == null) {
            // Compute the grid only one time
            grid = (BufferedImage)(this.createImage(w,h));
        }
        
        
        Graphics2D gc = grid.createGraphics();
        gc.clearRect(0, 0, w, h);
        for (int x=0; x<=20*gridSize; x+=gridSize) {gc.drawLine(x, 0, x, h);}
        for (int y=0; y<=15*gridSize; y+=gridSize) {gc.drawLine(0, y, w, y);}
        
        MotionVector[] mv = info.vectors;
        
        int radius = 2;
        float scale = 4.0f;
        for(int y=0; y < 15; y++){	
        	for(int x=0; x < 20; x++){	
        		int centerX = x * gridSize + gridSize / 2;
        		int centerY = y * gridSize + gridSize / 2;
        		int endX = (int) (centerX + mv[y*20 + x].x * scale);
        		int endY = (int) (centerY + mv[y*20 + x].y * scale);
        		gc.drawLine(centerX, centerY, endX, endY);
        		gc.drawOval(endX-radius,endY-radius,radius*2,radius*2);
        	}
        }
        
        // Draw the grid from the precomputed image
        g2.drawImage(grid, null, 0, 0);
        g2.drawString(indexName, w-50, h-30);
	}
	
	public void paintComponent(Graphics g) {
        super.paintComponent(g);       // paint background
        paintMotionInfo(g);
	}

	public void setMotionInfos(FrameMotionInfo[] infos) {
		this.infos = infos;
	}

	
	public void setMotionSegments(VideoSegment[] segments){
		for(int i=0; i<segments.length; i++){
			for(int j = segments[i].start; j <= segments[i].end; j++){
				indices.add(j);
			}
		}
	}

	@Override
	public void keyTyped(KeyEvent e) {
		char keyChar = e.getKeyChar();

		if(keyChar == 'd'){
			if(counter < indices.size()-1)
				counter ++;
		}
		else if(keyChar == 'a'){
			if(counter > 0) counter--;
		}
		
		int index = indices.get(counter);
		this.drawMotionInfo(infos[index], index);
	}

	@Override
	public void keyPressed(KeyEvent e) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void keyReleased(KeyEvent e) {
		// TODO Auto-generated method stub
		
	}
}
